package com.yanqu.road.server.manger.activity.horserun;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.horserun.config.*;
import com.yanqu.road.entity.enums.activity.horserun.eHorseRunAttrEnum;
import com.yanqu.road.entity.enums.activity.horserun.eHorseRunEventType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.activity.horserun.HorseRunConfig;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.HorseRunProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.horserun.HorseRunActivityModule;
import com.yanqu.road.server.gameplayer.module.activity.horserun.event.*;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class HorseRunMgr extends TempMgr {

    private static HorseRunConfig config;

    private static Map<String, HorseRunProto.HorseRunConfig.Builder> configMap = new ConcurrentHashMap<>();

    private static Random random = new Random();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static void reloadHorseRunConfig() {
        getLogger().info("reloadHorseRunConfig start");
        List<ActivityInfo> openActivityInfo = NormalActivityMgr.getOpenActivityInfoList(eActivityType.HorseRun.getValue());
        if (openActivityInfo == null || openActivityInfo.isEmpty()) {
            config = null;
            configMap.clear();
            getLogger().info("reloadHorseRunConfig end openActivityInfo is empty");
            return;
        }
        ActivityInfo activityInfo = openActivityInfo.get(0);
        Map<String, ActivityConfig> activityConfigMap = ActivityMgr.getActivityConfigMap(activityInfo.getActivityId());
        HorseRunConfig tempHorseRunConfig = new HorseRunConfig(activityInfo,activityConfigMap);

        config = tempHorseRunConfig;
        //重新生成config的msg
        configMap.clear();
        //所有在线玩家检测一下数据 下发配置
        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(HorseRunActivityModule.class).init();
        }

        getLogger().info("has horseRunActivity reloadHorseRunConfig end");
    }

    public static HorseRunConfig getConfig() {
        return config;
    }

    public static HorseRunProto.HorseRunConfig.Builder getConfigMsg(String language) {
        if (config == null) {
            return null;
        }
        if (configMap.containsKey(language)) {
            return configMap.get(language);
        }else {
            synchronized (configMap) {
                if (!configMap.containsKey(language)) {
                    HorseRunProto.HorseRunConfig.Builder horseRunConfig = buildConfig(language);
                    if (horseRunConfig != null) {
                        configMap.put(language, horseRunConfig);
                        return horseRunConfig;
                    }
                }
            }
        }
        return null;
    }

    public static HorseRunProto.HorseRunConfig.Builder buildConfig(String language) {
        if (config == null) {
            getLogger().error("buildConfig msg error config is null");
            return null;
        }

        HorseRunProto.HorseRunConfig.Builder builder = HorseRunProto.HorseRunConfig.newBuilder();

        for (HorseRunEquipConfig equipConfig:config.getEquipConfigs().values()){
            HorseRunProto.HorseRunEquipConfig.Builder equipConfigBuild = HorseRunProto.HorseRunEquipConfig.newBuilder();
            equipConfigBuild.setId(equipConfig.getId());
            equipConfigBuild.setLevel(equipConfig.getLevel());
            equipConfigBuild.setName(ServerLanguageMgr.getContent(equipConfig.getName(), language));
            equipConfigBuild.setPlace(equipConfig.getPlace());
            builder.addEquipConfig(equipConfigBuild);
        }

        for (HorseRunEventConfig eventConfig:config.getEventConfigs().values()){
            HorseRunProto.HorseRunEventConfig.Builder eventConfigBuild = HorseRunProto.HorseRunEventConfig.newBuilder();
            eventConfigBuild.setId(eventConfig.getId());
            eventConfigBuild.setAllMax(eventConfig.getAllMax());
            eventConfigBuild.setType(eventConfig.getType());
            eventConfigBuild.setShow(eventConfig.getShow());
            eventConfigBuild.setWeight(eventConfig.getWeight());
            eventConfigBuild.setParam(eventConfig.getParam());
            builder.addEventConfig(eventConfigBuild);
        }

        for (HorseRunLevelConfig levelConfig:config.getLevelConfigs().values()){
            HorseRunProto.HorseRunLevelConfig.Builder levelConfigBuild = HorseRunProto.HorseRunLevelConfig.newBuilder();
            levelConfigBuild.setId(levelConfig.getId());
            levelConfigBuild.setNeedExp(levelConfig.getNeedExp());
            levelConfigBuild.setAttribute(levelConfig.getAttribute());
            levelConfigBuild.setGetSkill(levelConfig.getGetSkill());
            builder.addLevelConfig(levelConfigBuild);
        }

        for (HorseRunRaceCourseConfig courseConfig:config.getCourseConfigMap().values()){
            HorseRunProto.HorseRunRaceCourseConfig.Builder courseConfigBuild = HorseRunProto.HorseRunRaceCourseConfig.newBuilder();
            courseConfigBuild.setId(courseConfig.getId());
            courseConfigBuild.setExp(courseConfig.getExp());
            courseConfigBuild.setTotalNum(courseConfig.getTotalNum());
            builder.addRaceCourseConfig(courseConfigBuild);
        }

        for (HorseRunSkillConfig skillConfig:config.getSkillConfigs().values()){
            HorseRunProto.HorseRunSkillConfig.Builder skillConfigBuild = HorseRunProto.HorseRunSkillConfig.newBuilder();
            skillConfigBuild.setId(skillConfig.getId());
            skillConfigBuild.setQuality(skillConfig.getQuality());
            skillConfigBuild.setType(skillConfig.getType());
            skillConfigBuild.setSkillNum(skillConfig.getSkillNum());
            skillConfigBuild.setWeight(skillConfig.getWeight());
            skillConfigBuild.setName(ServerLanguageMgr.getContent(skillConfig.getName(), language));
            skillConfigBuild.setAttributeType(skillConfig.getAttributeType());
            builder.addSkillConfig(skillConfigBuild);
        }

        for (HorseRunTurnTableConfig turnTableConfig:config.getTurnTableConfigs().values()){
            HorseRunProto.HorseRunTurnTableConfig.Builder turnTableConfigBuild = HorseRunProto.HorseRunTurnTableConfig.newBuilder();
            turnTableConfigBuild.setId(turnTableConfig.getId());
            turnTableConfigBuild.setType(turnTableConfig.getType());
            turnTableConfigBuild.setNum(turnTableConfig.getNum());
            turnTableConfigBuild.setIsSpecial(turnTableConfig.getIsSpecial());
            turnTableConfigBuild.setWeight(turnTableConfig.getWeight());
            builder.addTurnTableConfig(turnTableConfigBuild);
        }

        for (HorseRunTextConfig textConfig:config.getTextConfigs().values()){
            HorseRunProto.HorseRunTextConfig.Builder textConfigBuild = HorseRunProto.HorseRunTextConfig.newBuilder();
            textConfigBuild.setId(textConfig.getId());
            textConfigBuild.setType(textConfig.getType());
            textConfigBuild.setMeetText(ServerLanguageMgr.getContent(textConfig.getMeetText(), language));
            textConfigBuild.setDealText(ServerLanguageMgr.getContent(textConfig.getDealText(), language));
            builder.addTextConfig(textConfigBuild);
        }

        for (HorseRunBossConfig bossConfig:config.getBossConfigMap().values()){
            HorseRunProto.HorseRunBossConfig.Builder bossBuild = HorseRunProto.HorseRunBossConfig.newBuilder();
            bossBuild.setId(bossConfig.getId());
            bossBuild.setArtful(bossConfig.getArtful());
            bossBuild.setEnergy(bossConfig.getEnergy());
            bossBuild.setResistance(bossConfig.getResistance());
            bossBuild.setExp(bossConfig.getExp());
            bossBuild.addAllHighLevel(bossConfig.getHighLevel());
            bossBuild.addAllMidLevel(bossConfig.getMidLevel());
            bossBuild.addAllNormalLevel(bossConfig.getNormalLevel());
            builder.addBossConfig(bossBuild);
        }

        for (HorsRunBossNameConfig nameConfig:config.getBossNameConfigMap().values()){
            HorseRunProto.HorseRunBossNameConfig.Builder nameBuild = HorseRunProto.HorseRunBossNameConfig.newBuilder();
            nameBuild.setId(nameConfig.getId());
            nameBuild.setName(ServerLanguageMgr.getContent(nameConfig.getName(),language));
            nameBuild.setDealText(ServerLanguageMgr.getContent(nameConfig.getDealText(),language));
            nameBuild.setMeetText(ServerLanguageMgr.getContent(nameConfig.getMeetText(),language));
            builder.addBossNameConfig(nameBuild);
        }

        return builder;
    }

    /**
     * 获取技能配置
     */
    public static HorseRunSkillConfig getSkillConfig(int skillId){
        if (config == null){
            return null;
        }
        return config.getSkillConfigs().get(skillId);

    }

    /**
     * 获取初始额外属性
     */
    public static Map<Integer,Integer> getInitExtAttrMap(){
        if (config == null){
            return null;
        }
        Map<Integer,Integer> map = new ConcurrentHashMap<>();
        map.put(eHorseRunAttrEnum.energy.getValue(),0);
        map.put(eHorseRunAttrEnum.artful.getValue(),0);
        map.put(eHorseRunAttrEnum.resistance.getValue(),0);

        return map;
    }
    /**
     * 获取初始属性
     * @return
     */
    public static Map<Integer,Integer> getInitAttrLevelMap(){
        if (config == null){
            return null;
        }
        Map<Integer,Integer> map = new ConcurrentHashMap<>();
        map.put(eHorseRunAttrEnum.energy.getValue(),0);
        map.put(eHorseRunAttrEnum.artful.getValue(),0);
        map.put(eHorseRunAttrEnum.resistance.getValue(),0);

        return map;
    }

    /**
     * 计算属性值 1固定加成 2百分比加成
     * @param attrMap
     * @param skill
     * @return
     */
    public static Map<Integer,Integer> calTotalAttr(Map<Integer,Integer> attrMap,List<Integer> skill){
        if(config == null || skill == null ||skill.isEmpty()){
            return new HashMap<>(attrMap);
        }

        Map<Integer, Integer> addMap = getCalAttrMap();
        Map<Integer, Integer> percentageMap = getCalAttrMap();

        Map<Integer,Integer> resultAttr = new HashMap<>();

        for (int skillId:skill){
            HorseRunSkillConfig skillConfig = getSkillConfig(skillId);
            if (skillConfig == null){
                getLogger().error("小马快跑技能配置错误 ID{}",skillId);
                continue;
            }
            int attributeType = skillConfig.getAttributeType();
            if (skillConfig.getType() == 1){
                addMap.put(attributeType,addMap.get(attributeType) + skillConfig.getSkillNum());
            }else if (skillConfig.getType() == 2){
                percentageMap.put(attributeType,percentageMap.get(attributeType) + skillConfig.getSkillNum());
            }
        }

        for (Map.Entry<Integer,Integer> entry:attrMap.entrySet()){
            int attrType =entry.getKey();
            int attrResult = BigDecimal.valueOf(entry.getValue() + addMap.get(attrType)).multiply(BigDecimal.valueOf(1000 + percentageMap.get(attrType))).divide(BigDecimal.valueOf(1000),2, RoundingMode.DOWN).intValue();
            resultAttr.put(attrType,attrResult);
        }

        return resultAttr;
    }
    
    public static Map<Integer,Integer> getCalAttrMap(){
        Map<Integer,Integer> map = new HashMap<>();
        map.put(eHorseRunAttrEnum.energy.getValue(),0);
        map.put(eHorseRunAttrEnum.artful.getValue(),0);
        map.put(eHorseRunAttrEnum.resistance.getValue(),0);
        return map;
    }

    /**
     * 通过属性值计算评分
     * @return
     */
    public static long getGradeByAttr(Map<Integer,Integer> totalAttrMap){
        long grade = 0;
        for (int attr : totalAttrMap.values()){
            grade += attr;
        }
        return grade;
    }

    /**
     * 随机一个属性出来
     * @return
     */
    public static int randomAttrType (){
        return random.nextInt(3)+1;
    }

    public static int randomBackGround(){
        return random.nextInt(3)+1;
    }

    public static List<Integer> getInitEquip(){
        List<Integer> equip = new ArrayList<>();
        equip.add(0);
        equip.add(0);
        equip.add(0);
        return equip;
    }

    public static Map<Integer,Integer> getInitEquipMap(){
        Map<Integer,Integer> map = new HashMap<>();
        map.put(1,1);
        map.put(2,2);
        map.put(3,3);
        return map;
    }

    public static List<Integer> getInitUnlockEquip(){
        List<Integer> unlockEquip = new ArrayList<>();
        unlockEquip.add(1);
        unlockEquip.add(2);
        unlockEquip.add(3);
        return unlockEquip;
    }



    public static HorseRunBaseEvent getEventByType(int type){
        if (type == eHorseRunEventType.attr.getValue()){
            return new HorseRunAttrAddEvent();
        }else if (type == eHorseRunEventType.exp.getValue()){
            return new HorseRunExpAddEvent();
        }else if (type == eHorseRunEventType.show.getValue()){
            return new HorseRunShowEvent();
        }else if (type == eHorseRunEventType.train.getValue()){
            return new HorseRunTrainEvent();
        }else if (type == eHorseRunEventType.addConfident.getValue()){
            return new HorseRunAddConfidentEvent();
        }else if (type == eHorseRunEventType.exploreStart.getValue()){
            return new HorseRunExploreParentEvent();
        }else if (type == eHorseRunEventType.deBuff.getValue()){
            return new HorseRunAttrReduceEvent();
        }else if (type == eHorseRunEventType.simpleBattle.getValue()){
            return new HorseRunSimpleBattleEvent();
        }else if (type == eHorseRunEventType.lottery.getValue()){
            return new HorseRunLotteryDrawEvent();
        } else if (type == eHorseRunEventType.card.getValue()){
            return new HorseRunCardEvent();
        } else if (type == eHorseRunEventType.bossBattle.getValue()){
            return new HorseRunBossBattleEvent();
        }else if (type == eHorseRunEventType.allAttrReduce.getValue()){
            return new HorseRunReduceAllAttrEvent();
        } else if (type == eHorseRunEventType.addConfidentMax.getValue()){
            return new HorseRunAddMaxConfidentEvent();
        }else if (type == eHorseRunEventType.startGame.getValue()){
            return new HorseRunStartGameEvent();
        }else if (type == eHorseRunEventType.allAttrAdd.getValue()){
            return new HorseRunAddAllAttrEvent();
        }
        return null;
    }



    public static List<Integer> getRandomExpEvent(){
        Map<Integer, Integer> expEventWeightMap = config.getExpEventNumWeightMap();
        int eventNum = WeightHelper.getRandomValue(expEventWeightMap);

        List<Integer> expEventStage = new ArrayList<>();
        //最后一关一定是boss 不管
        for (int i = 1;i < config.getStagePerProcess();i++){
            expEventStage.add(i);
        }
        Collections.shuffle(expEventStage);
        return expEventStage.subList(0,eventNum);
    }

    public static Map<Integer,Integer> getBaseAttrMap(Map<Integer,Integer> attrPointLevelMap, int level, Map<Integer, Integer> extAttr){
        HorseRunLevelConfig configById = config.getLevelConfigById(level);
        if (configById == null){
            return null;
        }
        int attrPointPerLevelAddAttr = config.getAttrPointPerLevelAddAttr();
        //拿个空的出来
        Map<Integer, Integer> calAttrMap = getCalAttrMap();
        //先给等级的基础值
        for (Map.Entry<Integer,Integer> entry:calAttrMap.entrySet()){
            entry.setValue(configById.getAttribute());
        }
        //再给属性的
        for (Map.Entry<Integer,Integer> entry: attrPointLevelMap.entrySet()){
            calAttrMap.put(entry.getKey(),calAttrMap.get(entry.getKey())+(attrPointPerLevelAddAttr * entry.getValue()));
        }
        //再加额外的
        for (Map.Entry<Integer,Integer> entry: extAttr.entrySet()){
            calAttrMap.put(entry.getKey(),calAttrMap.get(entry.getKey())+(entry.getValue()));
        }

        return calAttrMap;
    }

    public static void checkUpdateCondition(){
        if(config == null){
            return;
        }
        ActivityInfo activityInfo = config.getActivityInfo();
        if (activityInfo == null){
            return;
        }
        if (!ActivityMgr.activityInShowTime(activityInfo)){
            return;
        }
        for (GamePlayer player:GamePlayerMgr.getAllOnlinePlayer()){
            player.getModule(HorseRunActivityModule.class).updateUnionCondition();
        }
    }

    public static Random getRandom() {
        return random;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
